# Copyright (c) 2024 Huawei Technologies Co., Ltd.
# openUBMC is licensed under Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#         http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PSL v2 for more details.

# -*- coding: utf-8 -*-
"""
符号元信息系统
"""

from typing import List, Dict, Any, Optional, TypeVar, TYPE_CHECKING
from dataclasses import dataclass, field
from enum import Enum, auto


if TYPE_CHECKING:
    from .ir.base import IRNode
    from .ir.declarations.typevar import IRTypeVar
    from .type_inference import InferenceContext
    from .template_param import TemplateParam

T = TypeVar("T")


class SymbolKind(Enum):
    """符号类型"""

    ANY = auto()
    VARIABLE = auto()
    FUNCTION = auto()
    CLASS = auto()
    MODULE = auto()
    PARAMETER = auto()
    ATTRIBUTE = auto()
    METHOD = auto()
    ENUM = auto()
    CLOSURE_VARIABLE = auto()  # 闭包变量
    ALIAS = auto()
    TYPE_PARAM = auto()


class TypeKind(Enum):
    """类型种类"""

    PRIMITIVE = auto()  # 基础类型 (int, str, bool, float)
    CLASS = auto()  # 类类型
    FUNCTION = auto()  # 函数类型
    MODULE = auto()  # 模块类型
    GENERIC = auto()  # 泛型类型 (List[T], Dict[K,V])
    UNION = auto()  # 联合类型 (Union[int, str])
    OPTIONAL = auto()  # 可选类型 (Optional[T])
    TUPLE = auto()  # 元组类型
    CALLABLE = auto()  # 可调用类型
    TEMPLATE = auto()  # 模板参数类型 (T, U, K, V)
    PROTOCOL = auto()  # 协议类型 (Iterable, Iterator, Callable)
    ANY = auto()  # Any 类型
    NONE = auto()  # None 类型
    NEVER = auto()  # Never 类型 (底类型)
    TYPE_PARAM = auto()  # 类型参数
    UNKNOWN = auto()  # 未知类型


@dataclass
class TypeInfo:
    """类型信息"""

    kind: TypeKind
    name: str
    module: Optional[str] = None
    args: List["TypeInfo"] = field(default_factory=list)  # 泛型参数
    attributes: Dict[str, "Symbol"] = field(default_factory=dict)  # 实例属性
    methods: Dict[str, "Symbol"] = field(default_factory=dict)  # 实例方法
    base_types: List["TypeInfo"] = field(default_factory=list)  # 基类
    return_type: Optional["TypeInfo"] = None  # 函数返回类型
    # 模板参数相关
    template_constraints: List[str] = field(default_factory=list)  # 模板约束
    template_bound: Optional[str] = None  # 模板边界

    # 新增模板相关字段
    is_template: bool = False  # 是否为模板类型
    template_params: List[str] = field(
        default_factory=list
    )  # 模板参数名 ["T"] 或 ["K", "V"]
    is_variadic_template: bool = False  # 是否为可变参数模板
    min_template_args: int = 0  # 最少模板参数数量
    max_template_args: Optional[int] = None  # 最多模板参数数量

    # 实例化相关
    is_instantiated: bool = False  # 是否为实例化类型
    template_base: Optional[str] = None  # 基础模板名称 "list" for "list[int]"
    instantiation_args: List["TypeInfo"] = field(default_factory=list)  # 实例化参数

    # C++ 代码生成相关
    pass_by: Optional[str] = (
        None  # 参数传递策略：'value', 'const_ref', 'rvalue_ref', 'auto'
    )

    # 协议相关字段 (Protocol Types)
    is_protocol: bool = False  # 是否为协议类型
    required_methods: List[str] = field(default_factory=list)  # 协议要求的方法
    cpp_concept: Optional[str] = None  # C++ concept 名称

    # 常量相关字段 (Compile-time Constants)
    is_constant: bool = False  # 是否是编译时常量
    constant_value: Optional[Any] = None  # 常量值（如果是常量）

    @staticmethod
    def any() -> "TypeInfo":
        return TypeInfo(TypeKind.ANY, "Any")

    @staticmethod
    def none() -> "TypeInfo":
        return TypeInfo(TypeKind.NONE, "None")

    @staticmethod
    def unknown() -> "TypeInfo":
        return TypeInfo(TypeKind.UNKNOWN, "Unknown")

    def __str__(self) -> str:
        if self.args:
            args_str = ", ".join(str(arg) for arg in self.args)
            return f"{self.name}[{args_str}]"
        return self.name

    def __eq__(self, other) -> bool:
        """类型信息相等性比较"""
        if not isinstance(other, TypeInfo):
            return False
        return (
            self.kind == other.kind
            and self.name == other.name
            and self.module == other.module
            and self.args == other.args
        )

    def __hash__(self) -> int:
        """支持TypeInfo作为字典键"""
        return hash((self.kind, self.name, self.module, tuple(self.args)))

    def is_compatible_with(self, other: "TypeInfo") -> bool:
        """检查类型兼容性"""
        if self == other:
            return True

        # Any 类型与所有类型兼容
        if self.kind == TypeKind.ANY or other.kind == TypeKind.ANY:
            return True

        # None 类型只与 Optional 兼容
        if self.kind == TypeKind.NONE:
            return other.kind == TypeKind.OPTIONAL

        # 数值类型兼容性
        if self.name in ["int", "float"] and other.name in ["int", "float"]:
            return True

        # 检查继承关系
        for base in self.base_types:
            if base.is_compatible_with(other):
                return True

        return False


def build_type_signature(type_info: TypeInfo) -> str:
    """基于现有 TypeInfo 构建类型签名"""
    if not type_info.args:
        return type_info.name

    # 递归构建参数签名，使用现有的 __str__ 方法
    arg_parts = []
    for arg in type_info.args:
        if arg is None:
            # 处理 None 参数（可能是类型推导失败）
            arg_parts.append("Any")
        elif arg.args:  # 嵌套泛型
            arg_parts.append(build_type_signature(arg))
        else:
            arg_parts.append(arg.name)

    return f"{type_info.name}[{', '.join(arg_parts)}]"


@dataclass
class Symbol:
    """统一符号表示

    将类型符号和函数符号统一存储，通过上下文区分不同用途。
    支持向后兼容的同时提供新的统一架构功能。
    """

    name: str
    kind: SymbolKind
    type_info: Optional[TypeInfo] = None
    module: Optional[str] = None
    line: int = 0
    column: int = 0
    is_imported: bool = False
    import_path: Optional[str] = None
    ir_node: Optional["IRNode"] = None  # 对应的IR节点引用
    scope_node: Optional["IRNode"] = None  # 符号所属的作用域节点
    is_static: bool = False  # 是否为静态成员（属性或方法）
    _signatures: List["Signature"] = field(
        default_factory=list, init=False, repr=False
    )  # 内部签名列表
    type_config: Optional[Dict] = None  # 类型配置信息（类型符号特有）
    priority: int = 0  # 符号优先级
    is_template_type: bool = False  # 是否为模板类型符号
    is_type_alias: bool = False  # 是否为类型别名
    canonical_name: Optional[str] = None  # 别名的规范名称
    _signatures_initialized: bool = field(
        default=False, init=False, repr=False
    )  # 签名是否已初始化

    # 新增：显式模板参数定义（替代 type_config 中的隐式定义）
    template_params: Optional[List["TemplateParam"]] = None  # 模板参数列表

    def __post_init__(self):
        if self.ir_node:
            self.ir_node.set_symbol(self)

    @property
    def signatures(self) -> List["Signature"]:
        """获取函数签名列表（延迟初始化）"""
        self.ensure_signatures_initialized()
        return self._signatures

    @signatures.setter
    def signatures(self, value: List["Signature"]) -> None:
        """设置函数签名列表"""
        self._signatures = value
        self._signatures_initialized = True

    def get_type_info(
        self, context: Optional["InferenceContext"] = None
    ) -> Optional[TypeInfo]:
        """获取类型信息，支持延迟计算"""
        if self.type_info:
            return self.type_info

        if self.ir_node is not None:
            type_info = self._compute_type_from_ir_node(context)
            self.set_type_info(type_info)
            return type_info

        return None

    def _compute_type_from_ir_node(
        self, context: Optional["InferenceContext"]
    ) -> Optional[TypeInfo]:
        """从IR节点计算类型信息"""
        if self.ir_node is None:
            return None

        # 优先使用缓存的类型信息
        cached_type = self.ir_node.get_extension_param("inferred_type")
        if cached_type:
            return cached_type

        from .type_inference import infer_type

        return infer_type(self.ir_node, context)

    def set_type_info(self, type_info: Optional[TypeInfo]):
        """设置类型信息"""
        if not type_info:
            return

        if self.type_info:
            return

        if self.ir_node:
            type_symbol = self.ir_node.lookup_symbol(
                type_info.name, symbol_kinds=[SymbolKind.TYPE_PARAM, SymbolKind.CLASS]
            )
            if type_symbol:
                self.type_config = type_symbol.type_config
        self.type_info = type_info

    def ensure_signatures_initialized(self) -> None:
        """确保签名已初始化（延迟初始化）"""
        if self._signatures_initialized:
            return

        # 标记为已初始化，避免递归
        self._signatures_initialized = True

        # 从 IR 节点初始化签名
        if self.ir_node and hasattr(self.ir_node, "create_signature"):
            try:
                signature = self.ir_node.create_signature()  # type: ignore
                if signature:
                    self._signatures.append(signature)
                    # 按优先级排序
                    self._signatures.sort(key=lambda x: x.priority, reverse=True)
            except Exception:
                # 如果创建签名失败（比如循环依赖），保持空列表
                # 这在构建缓存阶段是可以接受的
                pass

    def add_signature(self, signature: "Signature") -> None:
        """添加函数签名"""
        self._signatures.append(signature)
        # 按优先级排序
        self._signatures.sort(key=lambda x: x.priority, reverse=True)
        # 标记为已初始化
        self._signatures_initialized = True

    def find_matching_signature(
        self, args_types: Optional[List[TypeInfo]] = None
    ) -> Optional["Signature"]:
        """查找匹配的函数签名，优先选择精确匹配"""
        # signatures property 会自动触发延迟初始化
        if not self.signatures:
            return None

        # 如果没有参数类型，返回第一个签名
        if args_types is None:
            return self.signatures[0]

        # 收集所有匹配的签名及其匹配得分
        # matches_call_with_typeinfo 现在直接返回匹配得分
        matching_signatures = []
        for signature in self.signatures:
            score = signature.matches_call_with_typeinfo(self.name, args_types)
            if score > 0:  # score > 0 表示匹配
                matching_signatures.append((signature, score))

        if not matching_signatures:
            return None

        # 按得分排序，返回得分最高的（精确匹配优先）
        matching_signatures.sort(key=lambda x: x[1], reverse=True)
        return matching_signatures[0][0]

    def is_callable(self) -> bool:
        """检查符号是否可调用"""
        # signatures property 会自动触发延迟初始化
        return (
            self.kind == SymbolKind.FUNCTION
            or (self.kind == SymbolKind.CLASS and bool(self.signatures))
            or self.kind == SymbolKind.METHOD
        )

    def is_type(self) -> bool:
        """检查符号是否是类型"""
        return self.kind == SymbolKind.CLASS

    def is_variadic_template(self) -> bool:
        """检查是否为可变参数模板"""
        return bool(
            self.type_info
            and self.type_info.is_template
            and self.type_info.is_variadic_template
        )

    def get_template_params(self) -> List[str]:
        """获取模板参数列表"""
        return self.type_info.template_params if self.type_info else []

    def get_type_name(self) -> str:
        """获取类型名称"""
        type_info = self.get_type_info()
        return str(type_info) if type_info else "Unknown"

    def to_signature(self) -> Optional["Signature"]:
        """将符号转换为函数签名（仅适用于函数符号）"""
        if self.kind != SymbolKind.FUNCTION:
            return None

        type_info = self.get_type_info()

        # 从 IR 节点提取 callback_path（如果有）
        callback_path = None
        if self.ir_node and hasattr(self.ir_node, "get_extension_param"):
            callback_path = self.ir_node.get_extension_param("callback_path")

        # 如果有类型信息，使用类型信息
        if type_info:
            # 提取模板参数
            template_params = []
            template_param_mapping = {}

            for i, arg in enumerate(type_info.args):
                # 检查是否是模板参数（只检查 TypeKind.TEMPLATE）
                if arg.kind == TypeKind.TEMPLATE:
                    if arg.name not in template_params:
                        template_params.append(arg.name)

                    # 建立模板参数映射
                    if arg.name not in template_param_mapping:
                        template_param_mapping[arg.name] = {}
                    template_param_mapping[arg.name][f"param_{i}"] = i

            # 从 IR 节点提取参数名和参数覆盖信息（如果有）
            param_names = []
            param_overrides_dict = None
            if self.ir_node and hasattr(self.ir_node, "params"):
                for param in getattr(self.ir_node, "params", []):
                    param_names.append(param.name)
                param_overrides_dict = self.ir_node.get_extension_param(
                    "param_overrides"
                )

            return Signature(
                function_name=self.name,
                param_types=[str(arg) for arg in type_info.args],
                return_type=str(type_info.return_type),
                template_params=template_params,
                template_param_mapping=template_param_mapping,
                callback_path=callback_path,
                args=param_names,
                param_overrides=param_overrides_dict,
            )

        # 如果没有类型信息，尝试从 IR 节点提取
        if (
            self.ir_node
            and hasattr(self.ir_node, "node_type")
            and self.ir_node.node_type == "function"
        ):
            return self._extract_signature_from_ir_node()

        return None

    def _extract_signature_from_ir_node(self) -> Optional["Signature"]:
        """从函数 IR 节点提取签名信息"""
        if not self.ir_node:
            return None

        node = self.ir_node

        # 获取模块中定义的 TypeVar
        module_typevars = set()
        module = node.get_ir_module()
        if module:
            for module_node in module.get_child_nodes():
                if isinstance(module_node, "IRTypeVar"):
                    module_typevars.add(module_node.name)

        # 提取参数类型和参数名
        param_types = []
        param_names = []
        template_params = []
        template_param_mapping = {}

        # 优先使用IRFunctionNode的template_params（从签名推导的）
        if hasattr(node, "template_params") and getattr(node, "template_params"):
            template_params = list(getattr(node, "template_params"))

        if hasattr(node, "params"):
            for i, param in enumerate(getattr(node, "params", [])):
                param_type = param.type_annotation
                param_types.append(param_type)
                param_names.append(param.name)  # 添加参数名

                # 检查是否是模板参数（在模块中定义的 TypeVar，或在函数template_params中）
                if param_type and (
                    param_type in module_typevars or param_type in template_params
                ):
                    if param_type not in template_params:
                        template_params.append(param_type)

                    # 建立模板参数映射
                    if param_type not in template_param_mapping:
                        template_param_mapping[param_type] = {}
                    template_param_mapping[param_type][f"param_{i}"] = i

        # 提取返回类型
        return_type = getattr(node, "return_type", None) or "None"

        # 提取 callback_path（如果有 @mcpy_callback 注解）
        callback_path = None
        if hasattr(node, "get_extension_param"):
            callback_path = node.get_extension_param("callback_path")

        # 提取 param_overrides（如果有 @mcpy_param_override 注解）
        param_overrides = None
        if hasattr(node, "get_extension_param"):
            param_overrides = node.get_extension_param("param_overrides")

        sig = Signature(
            function_name=self.name,
            param_types=param_types,
            return_type=return_type,
            template_params=template_params,
            template_param_mapping=template_param_mapping,
            callback_path=callback_path,
            args=param_names,  # 添加参数名列表
        )

        # 保存参数覆盖信息
        if param_overrides:
            sig.param_overrides = param_overrides

        return sig

    def __str__(self) -> str:
        type_info = self.get_type_info()
        type_str = str(type_info) if type_info else "Unknown"
        return f"{self.name}: {type_str} ({self.kind.name})"


@dataclass
class Signature:
    """函数签名类

    用于表示内建函数的签名信息，包括参数类型、返回类型、模板参数等。
    """

    function_name: str
    param_types: List[str] = field(default_factory=list)
    return_type: str = "auto"
    template_params: List[str] = field(
        default_factory=list
    )  # 向后兼容：简单模板参数名列表
    emit_template: str = ""
    includes: List[str] = field(default_factory=list)
    priority: int = 0
    is_method: bool = False
    args: List[str] = field(default_factory=list)
    optional_params: List[int] = field(default_factory=list)
    is_mutating: bool = False  # 是否为修改方法（会改变对象状态）
    is_classmethod: bool = False  # 是否为类方法（静态方法，不需要实例）

    # 模板参数位置映射：{模板参数名: {'param_index': 参数索引, 'type_arg_index': 类型参数索引}}
    template_param_mapping: Dict[str, Dict[str, int]] = field(default_factory=dict)

    # 可选参数的默认值：{参数名: 默认值代码}
    param_defaults: Dict[str, str] = field(default_factory=dict)

    # 可选参数片段：{参数名: 片段模板}
    # 当参数未提供时，整个片段会被移除
    # 例如：{"start": ", {start}"} 表示未提供 start 时，", {start}" 整体被移除
    optional_fragments: Dict[str, str] = field(default_factory=dict)

    # 回调配置信息
    callback_path: Optional[str] = (
        None  # 自定义回调类路径，如 "mcpy.builtin.bool_callback:BoolFunctionCallback"
    )

    # 参数覆盖信息：{参数名: C++ 类型}
    # 用于处理 Python 参数类型与 C++ 实际期望类型不同的情况
    # 例如：argc: int 但 C++ 期望 int*，覆盖为 argc=Pointer[int]
    param_overrides: Optional[Dict[str, str]] = None

    # 类型变量约束信息：{类型变量名: {约束配置}}
    # 用于支持带约束的模板参数，如 T1: {constraints: ["Any", "dict"]}
    type_vars: Dict[str, Dict[str, Any]] = field(default_factory=dict)

    # 新增：详细的模板参数定义（包含约束信息）
    template_params_detailed: Optional[List["TemplateParam"]] = None

    # 宏函数标记：是否为 C++ 宏（需要特殊处理参数）
    is_macro: bool = False

    # 新增：模板参数推导映射
    # 记录哪些模板参数可以从哪些函数参数推导
    # 例如：{"T": [0, 1]} 表示 T 可以从第 0 和第 1 个参数推导
    template_inference_map: Dict[str, List[int]] = field(default_factory=dict)

    # 常量参数约束：需要编译时常量的参数名列表
    # 例如：["index"] 表示 index 参数必须是编译时常量
    constant_params: List[str] = field(default_factory=list)

    # 新增：可变参数信息
    variadic_param_index: Optional[int] = (
        None  # 可变参数在 template_params_detailed 中的索引
    )
    min_template_args: int = 0  # 最少模板参数数量（固定参数数量）
    max_template_args: Optional[int] = None  # 最多模板参数数量（None 表示无限制）

    def matches_call_with_typeinfo(
        self, function_name: str, arg_type_infos: List[TypeInfo]
    ) -> int:
        """检查函数调用是否匹配此签名，并返回匹配得分

        Args:
            function_name: 函数名
            arg_type_infos: 参数类型信息列表

        Returns:
            int: 匹配得分，0 表示不匹配，>0 表示匹配（得分越高匹配度越好）
                 - 精确匹配：每个参数 +10 分
                 - 兼容但需要转换：每个参数 +1 分
        """
        # 检查函数名是否匹配
        if self.function_name != function_name:
            return 0

        score = 0

        # 对于方法签名，param_types[0] 存储的是 owner_type（用于符号注册），而不是实际参数
        # 因此需要从 param_types 中提取实际参数类型（跳过 owner_type）
        #
        # 说明：
        # - 类方法：param_types[0] 是 owner_type（如 "dict[K, V]"），实际参数从 param_types[1] 开始
        # - 实例方法：param_types[0] 是 self 的类型（如 "list[T]"），实际参数从 param_types[1] 开始
        # - 全局函数：param_types[0] 就是实际参数，不需要跳过
        #
        # arg_type_infos 的情况：
        # - 类方法：通常不包含 owner_type（因为通过 Class.method() 调用时，owner_type 不在参数列表中）
        # - 实例方法：可能包含也可能不包含 self 的类型（取决于调用路径）
        #
        # 因此需要：
        # 1. 对于方法签名，总是跳过 param_types[0]（它是 owner_type，不是实际参数）
        # 2. 如果 arg_type_infos 的第一个元素是 owner_type，也需要跳过它

        effective_arg_type_infos = list(arg_type_infos)  # 创建副本以避免修改原始列表
        param_offset = 0  # 从 param_types 中提取实际参数类型的起始偏移量
        owner_type_score = 0  # owner_type 的匹配得分

        if self.is_method and self.param_types:
            # 方法签名：param_types[0] 是 owner_type，需要跳过
            param_offset = 1
            owner_type_in_param = self.param_types[0]

            # 检查 arg_type_infos 的第一个元素是否是 owner_type
            # 如果是，需要跳过它（因为它不是实际参数），但先计算 owner_type 的匹配得分
            if effective_arg_type_infos:
                first_arg = effective_arg_type_infos[0]
                if first_arg and first_arg.name:
                    # 提取 owner_type 的基础类型名（如 "dict[K, V]" -> "dict"）
                    owner_base_name = (
                        owner_type_in_param.split("[")[0]
                        if "[" in owner_type_in_param
                        else owner_type_in_param
                    )
                    # 如果第一个参数匹配 owner_type 的基础类型名或完整类型名，则跳过
                    if (
                        first_arg.name == owner_base_name
                        or first_arg.name == owner_type_in_param
                    ):
                        # 在跳过之前，先计算 owner_type 的匹配得分
                        # 这对于无参数方法（如 __len__）很重要，因为此时 owner_type 的匹配度是唯一区分标准
                        owner_type_score = self._calculate_owner_type_match_score(
                            owner_type_in_param, first_arg
                        )
                        effective_arg_type_infos = effective_arg_type_infos[1:]

        effective_param_types = (
            self.param_types[param_offset:] if param_offset > 0 else self.param_types
        )

        # 将 owner_type 的匹配得分加入总分
        # 注意：owner_type_score 已经在跳过 owner_type 之前计算了
        score += owner_type_score

        # 检查是否有可变参数 *args 或 **kwargs
        # 支持带类型注解的格式：*T_comparable, **kwargs_type
        has_variadic = any(
            p.startswith("*") and not p.startswith("**") for p in effective_param_types
        )
        has_kwargs = any(p.startswith("**") for p in effective_param_types)

        if has_kwargs:
            # 对于 **kwargs，找到其位置（支持带类型的格式）
            kwargs_index = next(
                i for i, p in enumerate(effective_param_types) if p.startswith("**")
            )
            # 固定参数数量（**kwargs 之前的参数）
            fixed_param_count = kwargs_index
            # 检查至少有足够的固定参数
            if len(effective_arg_type_infos) < fixed_param_count:
                return 0

            # 检查固定参数的类型匹配并计算得分
            for i in range(fixed_param_count):
                expected_type = effective_param_types[i]
                actual_type = effective_arg_type_infos[i]

                # 如果实际类型未知，给予基础分数
                if actual_type is None:
                    score += 1
                    continue

                # 精确类型匹配（优先级最高）
                if expected_type == actual_type.name:
                    score += 90
                # 泛型类型匹配（如 list[T] 匹配 list[dict]）
                elif self._matches_generic_type(expected_type, actual_type):
                    score += self._calculate_generic_type_score(
                        expected_type, actual_type
                    )
                # 模板参数匹配（使用约束评分）
                elif expected_type in self.template_params:
                    template_score = self._get_template_match_score(
                        expected_type, actual_type
                    )
                    if template_score == 0:
                        return 0  # 不满足约束
                    score += template_score
                # 兼容但需要转换
                elif self._type_matches(expected_type, actual_type):
                    score += 1
                else:
                    return 0  # 不匹配

            # **kwargs 部分，每个额外参数给予基础分数
            for i in range(fixed_param_count, len(effective_arg_type_infos)):
                score += 1

            return score
        elif has_variadic:
            # 对于可变参数，找到 *args 的位置（支持带类型的格式）
            variadic_index = next(
                i
                for i, p in enumerate(effective_param_types)
                if p.startswith("*") and not p.startswith("**")
            )
            variadic_param = effective_param_types[variadic_index]

            # 提取可变参数的类型约束（如果有）
            # 格式：*T_comparable -> T_comparable
            if variadic_param != "*args":
                variadic_type = variadic_param[1:]  # 去掉前导 *
            else:
                variadic_type = None

            # 固定参数数量（*args 之前的参数）
            fixed_param_count = variadic_index
            # 检查至少有足够的固定参数
            if len(effective_arg_type_infos) < fixed_param_count:
                return 0

            # 检查固定参数的类型匹配并计算得分
            for i in range(fixed_param_count):
                expected_type = effective_param_types[i]
                actual_type = effective_arg_type_infos[i]

                # 如果实际类型未知，给予基础分数
                if actual_type is None:
                    score += 1
                    continue

                # 精确类型匹配（优先级最高）
                if expected_type == actual_type.name:
                    score += 90
                # 泛型类型匹配（如 list[T] 匹配 list[dict]）
                elif self._matches_generic_type(expected_type, actual_type):
                    score += self._calculate_generic_type_score(
                        expected_type, actual_type
                    )
                # 模板参数匹配（使用约束评分）
                elif expected_type in self.template_params:
                    template_score = self._get_template_match_score(
                        expected_type, actual_type
                    )
                    if template_score == 0:
                        return 0  # 不满足约束
                    score += template_score
                # 兼容但需要转换
                elif self._type_matches(expected_type, actual_type):
                    score += 1
                else:
                    return 0  # 不匹配

            # 可变参数部分，检查类型约束
            for i in range(fixed_param_count, len(effective_arg_type_infos)):
                actual_type = effective_arg_type_infos[i]

                if variadic_type and actual_type:
                    # 有类型约束，检查是否满足
                    if variadic_type in self.template_params:
                        # 模板参数约束
                        template_score = self._get_template_match_score(
                            variadic_type, actual_type
                        )
                        if template_score == 0:
                            return 0  # 不满足约束
                        # 可变参数匹配给予较低分数（40分），低于具体类型匹配（90分）
                        score += min(40, template_score)
                    elif self._type_matches(variadic_type, actual_type):
                        # 类型匹配
                        score += 40
                    else:
                        return 0  # 类型不匹配
                else:
                    # 无类型约束或类型未知，给予基础分数
                    score += 1

            return score
        else:
            # 非可变参数的原有逻辑
            # 检查参数数量是否匹配（考虑可选参数）
            # 对于类方法，optional_params 的索引需要减去 param_offset
            effective_optional_params = (
                [
                    idx - param_offset
                    for idx in self.optional_params
                    if idx >= param_offset
                ]
                if param_offset > 0
                else self.optional_params
            )
            required_param_count = len(effective_param_types) - len(
                effective_optional_params
            )
            provided_param_count = len(effective_arg_type_infos)

            if provided_param_count < required_param_count:
                return 0
            if provided_param_count > len(effective_param_types):
                return 0

            # 检查参数类型是否匹配并计算得分
            for i, arg_type_info in enumerate(effective_arg_type_infos):
                if i >= len(effective_param_types):
                    break

                expected_type = effective_param_types[i]

                # 检查常量约束：如果该参数需要常量，但实际参数不是常量，则不匹配
                # 注意：i 是 effective_arg_type_infos 的索引（已跳过 owner_type），
                # 需要加上 param_offset 才能正确访问 self.args
                param_index = i + param_offset
                requires_constant = (
                    param_index < len(self.args)
                    and self.args[param_index] in self.constant_params
                )
                if requires_constant:
                    if arg_type_info is None or not arg_type_info.is_constant:
                        return 0  # 需要常量但不是常量，不匹配

                # 如果实际类型未知，给予基础分数
                if arg_type_info is None:
                    score += 1
                    continue

                # 精确类型匹配（优先级最高）
                if expected_type == arg_type_info.name:
                    score += 90
                    # 如果该参数需要常量且实际是常量，额外加分（表示更精确的匹配）
                    if requires_constant and arg_type_info.is_constant:
                        score += 10
                # 泛型类型匹配（如 list[T] 匹配 list[dict]）
                elif self._matches_generic_type(expected_type, arg_type_info):
                    # 泛型类型匹配的得分应该高于通用模板参数，但低于精确匹配
                    # 基础分：60
                    # 如果泛型参数有约束且匹配，额外加分
                    generic_score = self._calculate_generic_type_score(
                        expected_type, arg_type_info
                    )
                    score += generic_score
                # 模板参数匹配（使用约束评分）
                elif expected_type in self.template_params:
                    template_score = self._get_template_match_score(
                        expected_type, arg_type_info
                    )
                    if template_score == 0:
                        return 0  # 不满足约束
                    score += template_score
                # 兼容但需要转换
                elif self._type_matches(expected_type, arg_type_info):
                    score += 1
                else:
                    return 0  # 不匹配

            # 如果是无参数函数且参数数量匹配，给予基础分数（避免返回 0）
            if score == 0 and required_param_count == 0 and provided_param_count == 0:
                score = 1

            return score

    def _get_template_match_score(
        self, template_param: str, actual_type_info: TypeInfo
    ) -> int:
        """计算模板参数的匹配分数

        Args:
            template_param: 模板参数名（如 "T", "T1"）
            actual_type_info: 实际类型信息

        Returns:
            int: 匹配分数
                - 100: 精确约束匹配（实际类型在 constraints 列表中）
                - 50: 通用模板匹配（无约束或实际类型未知）
                - 0: 不匹配（有约束但实际类型不在列表中）
        """
        # 优先使用新的 template_params_detailed（如果有）
        if self.template_params_detailed:
            for param in self.template_params_detailed:
                if param.name == template_param:
                    return self._get_template_param_match_score(param, actual_type_info)

        # 回退到旧的 type_vars 机制（向后兼容）
        if self.type_vars and template_param in self.type_vars:
            type_var_config = self.type_vars[template_param]
            constraints = type_var_config.get("constraints", [])
            constraint_kind = type_var_config.get("constraint_kind")

            # 如果没有约束，任何类型都可以匹配（通用模板）
            if not constraints and not constraint_kind:
                return 50

            # 如果实际类型未知，给予基础分数
            if actual_type_info is None:
                return 50

            # 使用 TemplateParam 进行约束验证
            from mcpy.template_param import TemplateParam

            try:
                # 从配置创建 TemplateParam 对象
                param = TemplateParam.from_type_var_config(
                    template_param, type_var_config
                )

                # 使用 matches_type 方法验证约束
                if param.matches_type(actual_type_info):
                    return 100  # 满足约束
                else:
                    return 0  # 不满足约束
            except Exception:
                # 如果创建失败，回退到简单的类型列表验证
                if not constraints:
                    return 50  # 无约束

                # 简单约束：检查类型是否在列表中
                if actual_type_info.name in constraints:
                    return 100  # 满足约束
                else:
                    return 0  # 不满足约束

        # 无约束信息，通用模板匹配
        return 50

    def _get_template_param_match_score(
        self, template_param: "TemplateParam", actual_type_info: TypeInfo
    ) -> int:
        """使用 TemplateParam 计算匹配分数（新实现）

        Args:
            template_param: TemplateParam 对象
            actual_type_info: 实际类型信息

        Returns:
            int: 匹配分数
                - 100: 精确约束匹配
                - 50: 通用模板匹配（无约束）
                - 0: 不满足约束
        """
        from .template_param import ConstraintKind

        # 如果实际类型未知，给予基础分数
        if actual_type_info is None:
            return 50

        actual_type_name = actual_type_info.name

        # 根据约束类型进行验证
        if template_param.constraint_kind == ConstraintKind.NONE:
            # 无约束，任何类型都匹配
            return 50

        elif template_param.constraint_kind == ConstraintKind.UNION:
            # Union 约束：直接检查类型是否在允许列表中
            if actual_type_name in template_param.allowed_types:
                return 100  # 满足约束
            else:
                return 0  # 不满足约束

        elif template_param.constraint_kind == ConstraintKind.PROTOCOL:
            # Protocol 约束：检查是否实现了必需的方法
            # TODO: 实现协议检查（需要类型系统支持）
            # 目前简化处理：给予基础分数
            return 50

        elif template_param.constraint_kind == ConstraintKind.TEMPLATE:
            # Template 约束：检查是否匹配模板模式
            # TODO: 实现模板模式匹配
            # 目前简化处理：给予基础分数
            return 50

        # 未知约束类型
        return 50

    def _type_matches(self, expected_type: str, actual_type_info: TypeInfo) -> bool:
        """检查类型是否匹配

        Args:
            expected_type: 期望的类型字符串
            actual_type_info: 实际的类型信息对象

        Returns:
            bool: 是否匹配
        """
        # 如果实际类型未知，默认认为不匹配
        if actual_type_info is None:
            return False

        # 简化的类型匹配逻辑

        # 模板参数匹配（如 T, K, V）
        # 注意：这里只检查是否是模板参数，约束检查在 _get_template_match_score 中
        if expected_type in self.template_params:
            # 检查是否满足约束
            score = self._get_template_match_score(expected_type, actual_type_info)
            return score > 0

        # 直接类型匹配
        if expected_type == actual_type_info.name:
            return True

        # Any 类型匹配所有
        # 1. 签名中的 expected_type 是 "any" 或 "Any"
        # 2. actual_type_info 是 ANY 类型（可以匹配任何 expected_type）
        if expected_type.lower() == "any" or actual_type_info.kind == TypeKind.ANY:
            return True

        # 泛型类型匹配（如 list[T] 匹配 TypeInfo(name="list", args=[TypeInfo(name="int")])）
        if self._matches_generic_type(expected_type, actual_type_info):
            return True

        # None 类型与 Optional[T] 的兼容性
        # Optional[T] 就是 Union[T, None]，所以 None 应该能赋值给 Optional[T]
        if (
            expected_type.startswith("Optional[")
            and actual_type_info.kind == TypeKind.NONE
        ):
            return True

        # 基本类型兼容性
        basic_conversions = {
            "int": ["int", "float"],
            "float": ["int", "float", "double"],
            "str": ["str", "string"],
            "bool": ["bool", "int"],
        }

        if expected_type in basic_conversions:
            return actual_type_info.name in basic_conversions[expected_type]

        # 协议兼容性检查：如果期望类型是协议，检查实际类型是否满足该协议
        # 例如：期望Coroutine，实际是result，result满足Coroutine协议
        from mcpy.type_system import _satisfies_protocol

        if _satisfies_protocol(actual_type_info, expected_type):
            return True

        return False

    def _matches_generic_type(
        self, expected_type: str, actual_type_info: TypeInfo
    ) -> bool:
        """检查泛型类型是否匹配

        Args:
            expected_type: 期望的类型字符串，如 "list[T]"
            actual_type_info: 实际的类型信息对象，如 TypeInfo(name="list", kind=GENERIC, args=[TypeInfo(name="int")])

        Returns:
            bool: 是否匹配
        """
        # 检查期望类型是否是泛型类型（包含方括号）
        if "[" not in expected_type or "]" not in expected_type:
            return False

        # 解析期望的泛型类型
        try:
            base_name = expected_type.split("[")[0]
            template_part = expected_type[
                expected_type.index("[") + 1 : expected_type.rindex("]")
            ]

            # 检查实际类型的基础名称是否匹配
            # 特殊处理：检查 base_name 是否为 Protocol
            is_protocol_match = False
            if base_name != actual_type_info.name:
                # 可能是 Protocol 类型，需要检查 actual_type 是否满足 Protocol
                is_protocol_match = self._check_protocol_match(
                    base_name, actual_type_info
                )
                if not is_protocol_match:
                    return False

            # 检查实际类型是否是泛型类型
            if actual_type_info.kind != TypeKind.GENERIC:
                return False

            # 解析期望的模板参数（需要考虑嵌套括号）
            # 使用统一的 _split_template_args 函数（支持可变参数）
            from mcpy.builtin.builtin_table import _split_template_args

            template_args_raw = _split_template_args(template_part)

            # 检查模板参数数量是否匹配
            actual_args = actual_type_info.args or []

            # 检查是否有可变参数模板（如 Args...）
            # 使用统一的解析方式，而不是字符串解析
            has_variadic = False
            variadic_index = -1
            template_args = []
            for i, arg in enumerate(template_args_raw):
                # 检查是否为可变参数
                is_variadic = arg.endswith("...")
                param_name = arg[:-3].strip() if is_variadic else arg.strip()
                template_args.append(param_name)

                if is_variadic:
                    has_variadic = True
                    variadic_index = i

            # 特殊处理Coroutine协议：Coroutine[Any, Any, T]可以匹配任何满足Coroutine协议的泛型类型
            # 例如：Coroutine[Any, Any, int]可以匹配result[int]
            if is_protocol_match and base_name == "Coroutine":
                # Coroutine协议的第3个参数是返回值类型，其他参数是协变/逆变
                # 只需要匹配第3个参数（返回值类型）
                if len(template_args) >= 3 and len(actual_args) >= 1:
                    # 比较Coroutine的第3个参数与actual的第1个参数
                    expected_return_type = template_args[2]  # T
                    actual_return_type = actual_args[0]  # int

                    if expected_return_type in self.template_params:
                        # T是模板参数，可以匹配任何类型
                        return True
                    elif expected_return_type == actual_return_type.name:
                        # 精确匹配
                        return True
                    else:
                        return False
                else:
                    return False

            # 特殊处理Iterable协议：Iterable[T]可以匹配dict[K, V]
            # dict 迭代时返回键（K），所以 Iterable[T] 匹配 dict[K, V] 时，T 对应 K
            if is_protocol_match and base_name == "Iterable":
                # Iterable协议只有1个参数（元素类型）
                if len(template_args) >= 1 and len(actual_args) >= 1:
                    expected_element_type = template_args[0]  # T
                    actual_element_type = actual_args[
                        0
                    ]  # K（对于 dict）或 T（对于 list）

                    if expected_element_type in self.template_params:
                        # T是模板参数，可以匹配任何类型
                        return True
                    elif expected_element_type == actual_element_type.name:
                        # 精确匹配
                        return True
                    else:
                        return False
                else:
                    return False

            # 检查参数数量
            if has_variadic:
                # 有可变参数：实际参数数量应该 >= 可变参数位置
                if len(actual_args) < variadic_index:
                    return False
            else:
                # 无可变参数：参数数量必须完全匹配
                if len(template_args) != len(actual_args):
                    return False

            # 检查每个模板参数
            for i, expected_arg in enumerate(template_args):
                if i >= len(actual_args):
                    # 可变参数情况下，可能实际参数更多，这是允许的
                    if has_variadic and i >= variadic_index:
                        break
                    return False

                actual_arg = actual_args[i]

                if expected_arg in self.template_params:
                    # 期望的是模板参数（如 T），可以匹配任何实际类型
                    continue
                elif "[" in expected_arg:
                    # 期望的是嵌套泛型（如 tuple[K, V]），需要递归匹配
                    if not self._matches_nested_generic(expected_arg, actual_arg):
                        return False
                else:
                    # 期望的是具体类型，需要精确匹配
                    if expected_arg != actual_arg.name:
                        return False

            return True

        except (ValueError, IndexError, AttributeError):
            # 解析失败，不匹配
            return False

    def _check_protocol_match(
        self, protocol_name: str, actual_type_info: TypeInfo
    ) -> bool:
        """检查类型是否满足 Protocol

        Args:
            protocol_name: Protocol 名称（如 "Iterable"）
            actual_type_info: 实际类型信息（如 list[int]）

        Returns:
            bool: 是否满足 Protocol
        """
        # 导入必要的模块（延迟导入避免循环依赖）
        try:
            from mcpy.symbol_registry import get_global_registry
            from mcpy.template_param import TemplateParam

            registry = get_global_registry()

            # 查找 Protocol 定义
            protocol_symbol = registry._primitive_types.get(
                protocol_name
            ) or registry._template_types.get(protocol_name)

            if not protocol_symbol or not protocol_symbol.type_info:
                return False

            # 检查是否是 Protocol
            if not protocol_symbol.type_info.is_protocol:
                return False

            # 方式1：检查allowed_types（通过satisfies_protocols注册）
            # 例如：result通过satisfies_protocols=Coroutine注册到Coroutine.allowed_types
            protocol_config = (
                protocol_symbol.type_config
                if hasattr(protocol_symbol, "type_config")
                else None
            )
            if protocol_config and "allowed_types" in protocol_config:
                if actual_type_info.name in protocol_config["allowed_types"]:
                    return True

            # 方式2：检查实际类型的satisfies_protocols配置
            # 从符号表查找实际类型的符号
            from mcpy.type_system import _satisfies_protocol

            if _satisfies_protocol(actual_type_info, protocol_name):
                return True

            # 方式3：检查required_methods（原有逻辑）
            required_methods = protocol_symbol.type_info.required_methods
            if not required_methods:
                return False  # Protocol无required_methods且不在allowed_types中，不满足

            # 检查实际类型是否实现了所有 required_methods
            # 从符号表查询类型的方法集合
            actual_methods = TemplateParam._get_type_methods_from_registry(
                actual_type_info.name, node=None, registry=registry
            )

            # 检查是否满足所有 required_methods
            required_set = set(required_methods)
            return required_set.issubset(actual_methods)

        except Exception:
            # 出错时保守返回 False
            return False

    def _split_template_args(self, args_str: str) -> list:
        """分割模板参数，正确处理嵌套括号

        Args:
            args_str: 模板参数字符串，如 "tuple[K, V]" 或 "K, V"

        Returns:
            list: 分割后的参数列表

        Example:
            "tuple[K, V]" -> ["tuple[K, V]"]
            "K, V" -> ["K", "V"]
        """
        args = []
        bracket_count = 0
        current_arg = ""

        for char in args_str:
            if char == "," and bracket_count == 0:
                args.append(current_arg.strip())
                current_arg = ""
            else:
                if char == "[":
                    bracket_count += 1
                elif char == "]":
                    bracket_count -= 1
                current_arg += char

        if current_arg.strip():
            args.append(current_arg.strip())

        return args

    def _matches_nested_generic(
        self, expected_type_str: str, actual_type_info: TypeInfo
    ) -> bool:
        """递归匹配嵌套的泛型类型

        Args:
            expected_type_str: 期望的类型字符串（可能包含模板参数），如 "tuple[K, V]"
            actual_type_info: 实际的类型信息，如 TypeInfo(name="tuple", args=[str, int])

        Returns:
            bool: 是否匹配

        Example:
            expected: "tuple[K, V]"
            actual: TypeInfo(name="tuple", args=[TypeInfo(name="str"), TypeInfo(name="int")])
            返回: True（K 和 V 是模板参数，可以匹配任何类型）
        """
        # 解析期望的泛型类型
        try:
            if "[" not in expected_type_str:
                # 不是泛型，简单匹配名称
                return expected_type_str == actual_type_info.name

            base_name = expected_type_str.split("[")[0]
            template_part = expected_type_str[
                expected_type_str.index("[") + 1 : expected_type_str.rindex("]")
            ]

            # 检查基础名称是否匹配
            if base_name != actual_type_info.name:
                return False

            # 解析期望的模板参数（需要考虑嵌套括号）
            # 使用统一的 _split_template_args 函数（支持可变参数）
            from mcpy.builtin.builtin_table import _split_template_args

            template_args_raw = _split_template_args(template_part)
            actual_args = actual_type_info.args or []

            # 检查是否有可变参数模板（如 Args...）
            # 使用统一的解析方式，而不是字符串解析
            has_variadic = False
            variadic_index = -1
            template_args = []
            for i, arg in enumerate(template_args_raw):
                # 检查是否为可变参数
                is_variadic = arg.endswith("...")
                param_name = arg[:-3].strip() if is_variadic else arg.strip()
                template_args.append(param_name)

                if is_variadic:
                    has_variadic = True
                    variadic_index = i

            # 检查参数数量
            if has_variadic:
                # 有可变参数：实际参数数量应该 >= 可变参数位置
                if len(actual_args) < variadic_index:
                    return False
            else:
                # 无可变参数：参数数量必须完全匹配
                if len(template_args) != len(actual_args):
                    return False

            # 递归检查每个参数
            for i, expected_arg in enumerate(template_args):
                if i >= len(actual_args):
                    # 可变参数情况下，可能实际参数更多，这是允许的
                    if has_variadic and i >= variadic_index:
                        break
                    return False

                actual_arg = actual_args[i]

                if expected_arg in self.template_params:
                    # 模板参数，匹配任何类型
                    continue
                elif "[" in expected_arg:
                    # 嵌套泛型，递归匹配
                    if not self._matches_nested_generic(expected_arg, actual_arg):
                        return False
                else:
                    # 具体类型，需要精确匹配
                    if expected_arg != actual_arg.name:
                        return False

            return True
        except (ValueError, IndexError, AttributeError):
            return False

    def _calculate_generic_type_score(
        self, expected_type: str, actual_type_info: TypeInfo
    ) -> int:
        """计算泛型类型匹配的得分

        Args:
            expected_type: 期望的泛型类型字符串，如 "list[T]"
            actual_type_info: 实际的类型信息，如 TypeInfo(name="list", args=[TypeInfo(name="dict")])

        Returns:
            int: 匹配分数
                - 基础分 60：泛型类型匹配（如 list[T] 匹配 list[dict]）
                - 如果泛型参数有约束且匹配，额外加分
        """
        base_score = 60  # 泛型类型匹配的基础分数，高于通用模板(50)，低于精确匹配(90)

        try:
            # 解析期望的泛型类型
            template_part = expected_type[
                expected_type.index("[") + 1 : expected_type.rindex("]")
            ]
            template_args = [arg.strip() for arg in template_part.split(",")]
            actual_args = actual_type_info.args or []

            # 检查每个泛型参数是否满足约束
            extra_score = 0
            for expected_arg, actual_arg in zip(template_args, actual_args):
                if expected_arg in self.template_params:
                    # 计算模板参数的约束得分
                    template_score = self._get_template_match_score(
                        expected_arg, actual_arg
                    )
                    if template_score == 100:
                        # 如果模板参数有约束且精确匹配，额外加 10 分
                        extra_score += 10
                    elif template_score == 0:
                        # 如果不满足约束，返回 0
                        return 0

            return base_score + extra_score

        except (ValueError, IndexError, AttributeError):
            return base_score

    def _calculate_owner_type_match_score(
        self, owner_type_str: str, actual_type_info: TypeInfo
    ) -> int:
        """计算 owner_type 的匹配得分

        用于区分弱类型和强类型方法的匹配。例如：
        - tuple[()] 匹配 tuple[T, Args...] 应该得分更高（强类型匹配）
        - tuple[()] 匹配 tuple 应该得分较低（弱类型匹配）

        Args:
            owner_type_str: 签名中的 owner_type 字符串，如 "tuple" 或 "tuple[T, Args...]"
            actual_type_info: 实际的类型信息，如 TypeInfo(name="tuple", args=[])

        Returns:
            int: 匹配分数
                - 100: 精确匹配（强类型匹配，如 tuple[int, int] 匹配 tuple[T, Args...]）
                - 80: 泛型模板匹配（强类型匹配泛型，如 tuple[()] 匹配 tuple[T, Args...]）
                - 50: 基础类型匹配（弱类型匹配，如 tuple 匹配 tuple）
        """
        # 检查是否是泛型类型（包含模板参数）
        if "[" in owner_type_str:
            # 强类型（泛型模板）：如 tuple[T, Args...]
            # 解析 owner_type
            base_name = owner_type_str.split("[")[0]
            template_part = owner_type_str[
                owner_type_str.index("[") + 1 : owner_type_str.rindex("]")
            ]

            # 检查基础名称是否匹配
            if base_name != actual_type_info.name:
                return 0

            # 检查实际类型是否是泛型类型
            if actual_type_info.kind != TypeKind.GENERIC:
                return 0

            # 检查是否可以匹配泛型模板（使用 _matches_generic_type）
            if self._matches_generic_type(owner_type_str, actual_type_info):
                # 强类型匹配：给予高分（80），高于弱类型匹配（50）
                # 如果实际类型的参数数量与模板参数完全匹配，可以给更高分（100）
                from mcpy.builtin.builtin_table import _split_template_args

                template_args_raw = _split_template_args(template_part)
                actual_args = actual_type_info.args or []

                # 检查是否有可变参数
                has_variadic = any(arg.endswith("...") for arg in template_args_raw)
                if has_variadic:
                    # 可变参数模板，如果参数数量匹配（包括空参数列表），给予高分
                    # tuple[()] 匹配 tuple[T, Args...] 应该得高分
                    return 80
                else:
                    # 固定参数模板，如果参数数量完全匹配，给予最高分
                    if len(template_args_raw) == len(actual_args):
                        return 100
                    else:
                        return 0
            else:
                return 0
        else:
            # 弱类型（基础类型）：如 tuple
            # 检查基础名称是否匹配
            if owner_type_str == actual_type_info.name:
                # 弱类型匹配：给予较低分数（50），低于强类型匹配（80）
                return 50
            else:
                return 0

    def get_param_type_infos(
        self, template_substitutions: Optional[Dict[str, Any]] = None
    ) -> List[TypeInfo]:
        """获取参数类型信息列表

        Args:
            template_substitutions: 模板参数替换字典

        Returns:
            List[TypeInfo]: 参数类型信息列表
        """
        from mcpy.type_system import parse_type_with_context

        param_types = []
        for param_type_str in self.param_types:
            if param_type_str == "*args":
                # 跳过可变参数标记
                continue

            # 如果有模板参数替换
            if template_substitutions and self.template_params:
                for template_param, actual_type in template_substitutions.items():
                    if template_param in self.template_params:
                        # 将模板参数替换为实际类型
                        if hasattr(actual_type, "name"):
                            actual_type_str = actual_type.name
                        else:
                            actual_type_str = str(actual_type)

                        param_type_str = param_type_str.replace(
                            template_param, actual_type_str
                        )

            param_type = parse_type_with_context(param_type_str)
            if param_type:
                param_types.append(param_type)
        return param_types

    def get_return_type_info(
        self, template_substitutions: Optional[Dict[str, Any]] = None
    ) -> Optional[TypeInfo]:
        """获取返回类型信息

        Returns:
            Optional[TypeInfo]: 返回类型信息，如果没有返回类型则为None
        """
        from mcpy.type_system import parse_type_with_context

        if not self.return_type:
            return None

        return_type_str = self.return_type

        # 如果有模板参数替换
        if template_substitutions and self.template_params:
            for template_param, actual_type in template_substitutions.items():
                if template_param in self.template_params:
                    # 将模板参数替换为实际类型
                    if hasattr(actual_type, "name"):
                        actual_type_str = actual_type.name
                    else:
                        actual_type_str = str(actual_type)

                    return_type_str = return_type_str.replace(
                        template_param, actual_type_str
                    )

        return parse_type_with_context(return_type_str)

    def get_function_type_info(
        self, template_substitutions: Optional[Dict[str, Any]] = None
    ) -> TypeInfo:
        """获取函数类型信息

        Args:
            template_substitutions: 模板参数替换字典

        Returns:
            TypeInfo: 函数类型信息
        """
        param_types = self.get_param_type_infos(template_substitutions)
        return_type = self.get_return_type_info(template_substitutions)

        return TypeInfo(
            kind=TypeKind.FUNCTION,
            name=self.function_name,
            args=param_types,
            return_type=return_type,
            module="builtins",
        )


class ArgEffect(Enum):
    """参数效果类型"""

    READ = "read"  # 只读参数
    UPDATE = "update"  # 会被修改的参数
    READ_ONCE = "read_once"  # 只读一次（可优化）


class ArgPattern(Enum):
    """参数模式类型"""

    GEN = "Gen"  # 生成器表达式
    ITER = "Iter"  # 可迭代对象
    SCALAR = "Scalar"  # 标量值
    SIZED = "Sized"  # 有 size() 方法的对象
    CALLABLE = "Callable"  # 可调用对象
    ANY = "Any"  # 任意类型
    # 类型感知（MVP）
    LIST = "List"  # 列表/向量
    DICT = "Dict"  # dict
    STRING = "String"  # 字符串
    NUMERIC = "Numeric"  # 数值
    BOOLEAN = "Boolean"  # 布尔
    # 扩展类型感知模式
    TUPLE = "Tuple"  # 元组
    SET = "Set"  # 集合
    FUNCTION = "Function"  # 函数对象
    OPTIONAL = "Optional"  # 可选类型（Union[T, None]）
    UNION = "Union"  # 联合类型
    # 可变参数支持
    VARIADIC = "Variadic"  # 可变参数（*args）


@dataclass
class FunctionSignature:
    """函数签名"""

    args: List[str]  # 参数名
    arg_patterns: List[ArgPattern]  # 参数模式
    return_type: str  # 返回类型（字符串表示）
    effects: List[ArgEffect] = field(default_factory=list)  # 参数效果
    # 类型增强（可选）
    arg_types: List[str] = field(
        default_factory=list
    )  # 期望的参数类型（如 "List[int]"）
    type_constraints: Dict[str, str] = field(default_factory=dict)  # 形参名->约束表达式
    # 可变参数支持
    is_variadic: bool = False  # 是否为可变参数函数
    min_args: Optional[int] = None  # 最小参数数量（可变参数时使用）
    max_args: Optional[int] = None  # 最大参数数量（可变参数时使用，None表示无限制）
    variadic_pattern: Optional[ArgPattern] = None  # 可变参数的模式
    # 关键字参数支持
    kwonly_args: List[str] = field(default_factory=list)  # 仅关键字参数名
    kwonly_patterns: List[ArgPattern] = field(default_factory=list)  # 仅关键字参数模式
    kwonly_defaults: Dict[str, Any] = field(default_factory=dict)  # 关键字参数默认值
    kwonly_effects: List[ArgEffect] = field(default_factory=list)  # 关键字参数效果

    def __post_init__(self):
        # 如果包含 VARIADIC 模式，自动设置为可变参数
        if ArgPattern.VARIADIC in self.arg_patterns:
            self.is_variadic = True
            if self.min_args is None:
                # 找到 VARIADIC 之前的固定参数数量作为最小参数数
                variadic_index = self.arg_patterns.index(ArgPattern.VARIADIC)
                self.min_args = variadic_index
            if self.variadic_pattern is None:
                # 默认可变参数为 SCALAR 类型
                self.variadic_pattern = ArgPattern.SCALAR

        # 默认所有参数都是只读的
        if not self.effects:
            if self.is_variadic:
                # 对于可变参数，只为固定参数设置 effects
                fixed_arg_count = (
                    len(self.args) - 1
                    if ArgPattern.VARIADIC in self.arg_patterns
                    else len(self.args)
                )
                self.effects = [ArgEffect.READ] * fixed_arg_count
            else:
                self.effects = [ArgEffect.READ] * len(self.args)

        # 为关键字参数设置默认 effects
        if not self.kwonly_effects and self.kwonly_args:
            self.kwonly_effects = [ArgEffect.READ] * len(self.kwonly_args)

    def matches_arg_count(self, arg_count: int, kwarg_count: int = 0) -> bool:
        """检查参数数量是否匹配此签名

        Args:
            arg_count: 位置参数数量
            kwarg_count: 关键字参数数量
        """
        # 检查位置参数数量
        if not self.is_variadic:
            if len(self.args) != arg_count:
                return False
        else:
            min_count = self.min_args or 0
            max_count = self.max_args
            if max_count is None:
                if arg_count < min_count:
                    return False
            else:
                if not (min_count <= arg_count <= max_count):
                    return False

        # 检查关键字参数数量（不能超过定义的关键字参数数量）
        if kwarg_count > len(self.kwonly_args):
            return False

        return True

    def matches_kwargs(self, provided_kwargs: Dict[str, Any]) -> bool:
        """检查提供的关键字参数是否匹配此签名

        Args:
            provided_kwargs: 提供的关键字参数字典
        """
        # 检查所有提供的关键字参数是否都在定义中
        for kwarg_name in provided_kwargs.keys():
            if kwarg_name not in self.kwonly_args:
                return False

        # 检查所有必需的关键字参数（没有默认值的）是否都提供了
        for kwarg_name in self.kwonly_args:
            if (
                kwarg_name not in provided_kwargs
                and kwarg_name not in self.kwonly_defaults
            ):
                return False

        return True
